package com.chenfan.filestore.repository;

import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.messages.Bucket;
import lombok.SneakyThrows;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Component
public class MinioTemplate implements InitializingBean {
    public static final String DEFAULT_BUCKETNAME = "eop";
    @Value("${minio.endpoint:http://10.228.86.202:9000/}")
    private String endpoint;
    @Value("${minio.accessKey:minioadmin}")
    private String accessKey;
    @Value("${minio.secretKey:minioadmin}")
    private String secretKey;
    private MinioClient client;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.hasText(endpoint, "Minio url 为空");
        Assert.hasText(accessKey, "Minio accessKey为空");
        Assert.hasText(secretKey, "Minio secretKey为空");
        this.client = new MinioClient(endpoint, accessKey, secretKey);
    }

    /**
     * 创建bucket
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public void createBucket(String bucketName) {
        if (!client.bucketExists(bucketName)) {
            client.makeBucket(bucketName);
        }
    }

    /**
     * 获取全部bucket
     * <p>
     * https://docs.minio.io/cn/java-client-api-reference.html#listBuckets
     */
    @SneakyThrows
    public List<Bucket> getAllBuckets() {
        return client.listBuckets();
    }

    /**
     * 根据bucketName获取信息
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public Optional<Bucket> getBucket(String bucketName) {
        return client.listBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
    }

    /**
     * 根据bucketName删除信息
     *
     * @param bucketName bucket名称
     */
    @SneakyThrows
    public void removeBucket(String bucketName) {
        client.removeBucket(bucketName);
    }

    private ObjectStat getFile(String bucketName, String fileName){
        try{
          return  client.statObject(bucketName, fileName);
        }catch (Exception e){

        }
        return null;
    };
    /**
     * 根据文件前置查询文件
     *
     * @param bucketName bucket名称
     * @param prefix     前缀
     * @param recursive  是否递归查询
     * @return MinioItem 列表
     */
    @SneakyThrows
    public ObjectStat getAllObjectsByPrefix(String bucketName, String prefix, boolean recursive) {
//        {"jpg", "bmp", "jpeg", "png", "gif", "tif", "pcx", "tga", "exif", "exif", "svg", "psd", "cdr", "pcd", "dxf", "ufo", "eps", "ai", "raw", "WMF", "webp"}

//        Iterable<Result<Item>> objectsIterator = client.listObjects(bucketName, prefix, recursive);
//        Iterable<Result<Item>> objectsIterator = client.listObjects(bucketName, prefix, recursive);
        ObjectStat objectStat = getFile(bucketName, prefix);
        if (objectStat != null) {
            return objectStat;

        }

        objectStat =getFile(bucketName, prefix + ".jpg");
        if (objectStat != null) {
            return objectStat;

        }
        objectStat =getFile(bucketName, prefix + ".JPG");
        if (objectStat != null) {
            return objectStat;

        }
        objectStat =getFile(bucketName, prefix + ".jpeg");
        if (objectStat != null) {
            return objectStat;

        }
        objectStat = getFile(bucketName, prefix + ".JPEG");
        if (objectStat != null) {
            return objectStat;

        }
        objectStat = getFile(bucketName, prefix + ".png");
        if (objectStat != null) {
            return objectStat;

        }
        objectStat =getFile(bucketName, prefix + ".PNG");
        if (objectStat != null) {
            return objectStat;

        }

        objectStat = getFile(bucketName, prefix + ".doc");
        if (objectStat != null) {
            return objectStat;

        }

        objectStat = getFile(bucketName, prefix + ".DOC");
        if (objectStat != null) {
            return objectStat;

        }

        objectStat =getFile(bucketName, prefix + ".csv");
        if (objectStat != null) {
            return objectStat;

        }

        objectStat = getFile(bucketName, prefix + ".xlsx");
        if (objectStat != null) {
            return objectStat;

        }


        return objectStat;
//        if (objectsIterator != null) {
//            Iterator<Result<Item>> iterator = objectsIterator.iterator();
//            if (iterator != null) {
//                while (iterator.hasNext()) {
//                    Result<Item> result = iterator.next();
//                    Item item = result.get();
//                    list.add(item);
//                }
//            }
//        }

    }

    /**
     * 获取文件外链
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param expires    过期时间 <=7
     * @return url
     */
    @SneakyThrows
    public String getObjectURL(String bucketName, String objectName, Integer expires) {
        return client.presignedGetObject(bucketName, objectName, expires);
    }

    /**
     * 获取文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @return 二进制流
     */
    @SneakyThrows
    public InputStream getObject(String bucketName, String objectName) {
        return client.getObject(bucketName, objectName);
    }

    /**
     * 上传文件 带文件类型
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param stream     文件流
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
     */
    public void putObject(String bucketName, String objectName, InputStream stream, String contentType) throws Exception {
        client.putObject(bucketName, objectName, stream, contentType);
    }

    /**
     * 上传文件 带文件类型
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @param stream     文件流
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
     */
    public void putObject(String bucketName, String objectName, InputStream stream, Long size, Map<String, String> headerMap) throws Exception {
        client.putObject(bucketName, objectName, stream, size, headerMap);
    }


    /**
     * 上传文件
     *
     * @param bucketName  bucket名称
     * @param objectName  文件名称
     * @param stream      文件流
     * @param size        大小
     * @param contextType 类型
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#putObject
     */
    public void putObject(String bucketName, String objectName, InputStream stream, long size, String contextType) throws Exception {
        client.putObject(bucketName, objectName, stream, size, contextType);
    }


    /**
     * 获取文件信息, 如果抛出异常则说明文件不存在
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
     */
    public ObjectStat getObjectInfo(String bucketName, String objectName) throws Exception {
        return client.statObject(bucketName, objectName);
    }

    /**
     * 删除文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#removeObject
     */
    public void removeObject(String bucketName, String objectName) throws Exception {
        client.removeObject(bucketName, objectName);
    }
}